package com.studerb.view.newsGroups;

import static com.studerb.util.Constants.EVENT_SERVICE_NAME;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventSubscriber;
import org.springframework.beans.factory.annotation.Autowired;

import com.studerb.events.NewsGroupEvent;
import com.studerb.events.TaskEvent;
import com.studerb.events.listener.AbstractTaskListener;
import com.studerb.model.NewsGroup;
import com.studerb.service.interfaces.IHeaderService;
import com.studerb.service.interfaces.INewsGroupService;
import com.studerb.util.Util;
import com.studerb.view.headers.HeadersTabbedPane;

public class NewsGroupDetailsPane extends JPanel implements ActionListener {
	Logger logger = Logger.getLogger(NewsGroupDetailsPane.class);
	@Autowired private IHeaderService headerService;
	@Autowired private INewsGroupService newsGroupService;
	@Autowired private HeadersTabbedPane headersTabbedPane;
	private JLabel nameLabel;
	private JTextField nameField;
	private JLabel postsCountLabel;
	private JTextField postsCountField;
	private JLabel headersCountLabel;
	private JTextField lastUpdatedHeadersField;
	private JLabel lastUpdatedHeadersLabel;
	private JTextField headersCountField;
	private NewsGroup currentNewsGroup = null;
	private JButton downloadAllHeadersButton;
	private JButton viewHeadersButton;
	private JButton downloadNewHeadersButton;

	@Override public void actionPerformed(ActionEvent e) {
		if (e.getSource() == downloadAllHeadersButton) {
			downloadAllHeaders();
		}
		else if (e.getSource() == viewHeadersButton) {
			viewHeaders();
		}
		else if (e.getSource() == downloadNewHeadersButton) {
			downloadNewHeaders();
		}
	}

	private void downloadAllHeaders() {
		logger.debug("Action Performed - downloading all headers for: " + currentNewsGroup.getGroupName());
		try {
			headerService.downloadAllHeaders(currentNewsGroup, new XoverAllTaskListener());
		}
		catch (Exception e) {
			JOptionPane.showMessageDialog(this, "Error: " + ExceptionUtils.getRootCauseMessage(e));
			return;
		}
		downloadAllHeadersButton.setEnabled(false);
		downloadNewHeadersButton.setEnabled(false);
	}

	private void downloadNewHeaders() {
		logger.debug("Action Performed - downloading new headers for: " + currentNewsGroup.getGroupName());
		try {
			headerService.downloadNewHeaders(currentNewsGroup, new XoverAllTaskListener());
		}
		catch (Exception e) {
			JOptionPane.showMessageDialog(this, "Error: " + ExceptionUtils.getRootCauseMessage(e));
			return;
		}
		downloadAllHeadersButton.setEnabled(false);
		downloadNewHeadersButton.setEnabled(false);
	}

	public void init() {
		initComponents();
		postsCountField.setEditable(false);
		nameField.setEditable(false);
		headersCountField.setEditable(false);
		lastUpdatedHeadersField.setEditable(false);
		setNullNewsGroup();
		downloadAllHeadersButton.addActionListener(this);
		viewHeadersButton.addActionListener(this);
		downloadNewHeadersButton.addActionListener(this);
		AnnotationProcessor.process(this);
	}

	public void initComponents() {
		this.setLayout(new MigLayout(new LC().insets("30")));
		downloadAllHeadersButton = new JButton("Download All Headers");
		add(downloadAllHeadersButton, "wrap");

		viewHeadersButton = new JButton("View Headers");
		add(viewHeadersButton, "wrap");

		downloadNewHeadersButton = new JButton("Download New Headers");
		add(downloadNewHeadersButton, "wrap");

		nameLabel = new JLabel("NewsGroup");
		add(nameLabel);

		nameField = new JTextField(30);
		add(nameField, "wrap");

		postsCountLabel = new JLabel("Posts");
		add(postsCountLabel);

		postsCountField = new JTextField(10);
		add(postsCountField, "wrap");

		headersCountLabel = new JLabel("Downloaded Headers");
		add(headersCountLabel);

		headersCountField = new JTextField(10);
		add(headersCountField, "wrap");

		lastUpdatedHeadersLabel = new JLabel("Last Updated Headers");
		add(lastUpdatedHeadersLabel);

		lastUpdatedHeadersField = new JTextField(30);
		add(lastUpdatedHeadersField, "wrap");
	}

	@EventSubscriber(eventServiceName = EVENT_SERVICE_NAME) public void onEvent(NewsGroupEvent evt) {
		NewsGroupEvent.EventType eventType = evt.getType();
		NewsGroup newsGroup = evt.getNewsGroup();
		switch (eventType) {
		case ALL_REFRESHED:
			setNullNewsGroup();
			break;
		case UPDATED: // fall through to HEADERS
		case HEADERS:
			if (newsGroup.equals(currentNewsGroup)) {
				this.setSelectedNewsGroup(newsGroup);
			}
			break;

		default:
			break;
		}
	}

	private void setNullNewsGroup() {
		nameField.setText(null);
		postsCountField.setText(null);
		headersCountField.setText(null);
		downloadAllHeadersButton.setEnabled(false);
		viewHeadersButton.setEnabled(false);
		downloadNewHeadersButton.setEnabled(false);
		lastUpdatedHeadersField.setText(null);
	}

	public void setSelectedNewsGroup(NewsGroup newsGroup) {
		currentNewsGroup = newsGroup;

		if (!newsGroup.isSubscribed()) {
			setNullNewsGroup();
		}
		else {
			nameField.setText(currentNewsGroup.getGroupName());
			postsCountField.setText(String.valueOf(currentNewsGroup.getPostsCount()));
			headersCountField.setText(String.valueOf(newsGroupService.getHeaderCount(currentNewsGroup)));
			downloadAllHeadersButton.setEnabled(true);
			viewHeadersButton.setEnabled(true);
			downloadNewHeadersButton.setEnabled(true);
			String headersUpdated = currentNewsGroup.getLastUpdatedHeaders() == null ? "Never" : Util.getSimpleDateTime(currentNewsGroup.getLastUpdatedHeaders());
			lastUpdatedHeadersField.setText(headersUpdated);
		}
	}

	private void viewHeaders() {
		try {
			downloadAllHeadersButton.setEnabled(false);
			headersTabbedPane.addNewHeadersTab(currentNewsGroup);
		}
		catch (Exception e) {
			JOptionPane.showMessageDialog(this, ExceptionUtils.getRootCauseMessage(e));
		}
	}

	class XoverAllTaskListener extends AbstractTaskListener<Void, Void> {
		@Override public void finished(TaskEvent<Void> event) {
			downloadAllHeadersButton.setEnabled(true);
			downloadNewHeadersButton.setEnabled(true);
		}
	}
}
